package data

import (
	"bytes"
	"database/sql"
	"fmt"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
	"strings"
	"time"
)

type SocialRepo struct{}

type ChatSessionDto struct {
	Id           int64  `orm:"pk;auto;column(id)"`
	SessionKey   string `orm:"column(session_key)"`
	Participants string `orm:"participants"`
}

type ChatParticipantDto struct {
	Id            int64  `orm:"pk;auto;column(id)"`
	SessionKey    string `orm:"column(session_key)"`
	ParticipantId string `orm:"column(participant_id)"`
}

type ChatLogDto struct {
	Id        int64  `orm:"pk;auto;column(id)"`
	Text      string `orm:"column(text)"`
	SenderId  string `orm:"column(sender_id)"`
	MessageId string `orm:"column(message_id)"`
	Time      string `orm:"column(create_time)"`
}

func init() {
	orm.RegisterModel(new(ChatSessionDto), new(ChatParticipantDto))
}

func (dto *ChatSessionDto) TableName() string {
	return "chat_session"
}

func (dto *ChatParticipantDto) TableName() string {
	return "chat_participant"
}

func (repo SocialRepo) AddChatSession(sessionKey string, participants []string) (err error) {
	var created bool
	var parts string
	o := orm.NewOrm()
	o.Using("social")
	if len(participants) > 0 {
		for _, p := range participants {
			parts += "," + p
		}
		session := ChatSessionDto{SessionKey: sessionKey, Participants: strings.TrimLeft(parts, ",")}
		if created, _, err = o.ReadOrCreate(&session, "SessionKey"); created {
			if len(participants) > 0 {
				list := make([]ChatParticipantDto, len(participants))
				for idx, p := range participants {
					list[idx] = ChatParticipantDto{SessionKey: sessionKey, ParticipantId: p}
				}
				_, err = o.InsertMulti(10, list)
			}
		}

	}

	return err
}

func (repo SocialRepo) AddChatLog(sessionKey, text, senderId, messageId string) (id int64, err error) {
	var num int64
	var result sql.Result
	o := orm.NewOrm()
	o.Using("social")
	if result, err = o.Raw(fmt.Sprintf(SQL_Social_Add_Chat_Log, text, senderId, messageId), sessionKey).Exec(); err == nil {
		if num, err = result.RowsAffected(); num > 0 {
			id, err = result.LastInsertId()
		}
	}
	return
}

func (repo SocialRepo) GetChatLogs(sessionKey string, offset int64) (list []ChatLogDto, err error) {
	chatSession := ChatSessionDto{SessionKey: sessionKey}
	o := orm.NewOrm()
	o.Using("social")
	if err = o.Read(&chatSession, "SessionKey"); err == nil {
		if chatSession.Id > 0 {
			_, err = o.Raw(SQL_Social_Get_Chat_Logs, chatSession.Id, time.Now().AddDate(0, 0, -3).Format("2006-01-02"), offset).QueryRows(&list)
		}
	}
	return
}

func (repo SocialRepo) GetChatSessions(memberId string, pageNo, pageSize int) (list []ChatSessionDto, err error) {
	var num int64
	var lists []orm.ParamsList
	o := orm.NewOrm()
	o.Using("social")
	if num, err = o.Raw(fmt.Sprintf(SQL_Social_Get_Participant_Session_Id, (pageNo-1)*pageSize, pageSize), memberId).ValuesList(&lists); num >= 1 {
		var buffer bytes.Buffer
		for _, item := range lists {
			buffer.WriteString(fmt.Sprintf("'%s',", item[0].(string)))
		}

		in := strings.TrimRight(buffer.String(), ",")
		_, err = o.Raw(fmt.Sprintf(SQL_Social_Get_All_Participants, in)).QueryRows(&list)
	}
	return
}
